package com.jielin.handling;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.github.pagehelper.PageHelper;
import com.jielin.handling.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 类名称：AppMain
 * 创建人：zhanglongdeng@163.com
 * 创建时间：2019年3月5日 下午3:06:04
 * 类描述：
 *
 * @SpringBootApplication ---> 扫描同级目录及其子目录下的注解
 * @EnableTransactionManagement ---> service实现类中加入事务注解，需要此处添加该注解
 * @MapperScan ---> 全局扫描mapper接口
 * @ServletComponentScan ---> 扫描过滤器
 */
@SpringBootApplication
@EnableTransactionManagement
@MapperScan(basePackages = {"com.jielin.handling.mapper"})
@ServletComponentScan("com.jielin.handling.web.filter")
@Slf4j
//@Configuration
public class AppMain extends SpringBootServletInitializer {

    final static String _DATE_FORMAT = DateUtil.DATE_FORMAT_MINUS;

    /**
     * 解决ie数据保存出现下载对话框的问题
     * 注入Bean : HttpMessageConverters，以支持fastjson
     *
     * @return
     */
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        // 定义一个转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 添加fastjson的配置信息 比如 ：是否要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // 这里就是核心代码了，WriteMapNullValue把空的值的key也返回
        fastJsonConfig.setSerializerFeatures(
                //保留map空的字段
                SerializerFeature.WriteMapNullValue,
                // 将String类型的NULL转化为""
                SerializerFeature.WriteNullStringAsEmpty,
                // 将Number类型的NULL转化为0
                SerializerFeature.WriteNullNumberAsZero,
                // 将List类型的NULL转成[]
                SerializerFeature.WriteNullListAsEmpty,
                // 将Boolean类型的NULL转化为false
                SerializerFeature.WriteNullBooleanAsFalse,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect);

        //如果时间类型值为null，则返回空串
        ValueFilter dateFilter = (Object var1, String var2, Object var3) -> {
            try {
                if (var3 == null && var1 != null && Date.class.isAssignableFrom(var1.getClass().getDeclaredField(var2).getType())) {
                    return "";
                }
            } catch (Exception e) {
            }
            return var3;
        };
        fastJsonConfig.setSerializeFilters(dateFilter);

        fastJsonConfig.setDateFormat(_DATE_FORMAT);

        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();

        // 处理中文乱码问题
        fastJsonConfig.setCharset(Charset.forName("UTF-8"));
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        // IE浏览器获取后台返回JSON下载问题的解决办法
        // 原因: IE 默认接收 text/html 类型返回值，遇到返回 json、xml 数据时，会当成文件提示下载保存
        fastMediaTypes.add(new MediaType("text", "plain", Charset.forName("UTF-8")));
        fastMediaTypes.add(new MediaType("text", "html", Charset.forName("UTF-8")));
        fastMediaTypes.add(new MediaType("text", "json", Charset.forName("UTF-8")));
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        // 在转换器中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);

        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        stringConverter.setDefaultCharset(Charset.forName("UTF-8"));
        stringConverter.setSupportedMediaTypes(fastMediaTypes);

        // 将转换器添加到converters中
        return new HttpMessageConverters(stringConverter, fastConverter);
    }

    @Bean
    public PageHelper pageHelper() {
        //配置MYBATIS的分页插件pageHelper
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("offsetAsPageNum", "true");
        properties.setProperty("rowBoundsWithCount", "true");
        properties.setProperty("reasonable", "true");
        //配置MYSQL数据库的方言
        properties.setProperty("dialect", "mysql");
        pageHelper.setProperties(properties);
        return pageHelper;
    }

    @Bean
    public Object testBean(PlatformTransactionManager platformTransactionManager) {
        log.info("Transaction Type >>>>>> {}", platformTransactionManager.getClass().getName());
        return new Object();
    }

    public static void main(String[] args) {
        SpringApplication.run(AppMain.class, args);
    }
}
